#include "main.h"
//// C lib
//#include <stdlib.h>
//#include <string.h>
//#include <stdio.h>
//// system
//#include "delay.h"
//// wifi
//#include "WIFI_config.h"
//#include "cJSON.h"


static char* ESP8266_check_cmd(char *str);
static char ESP8266_send_cmd(char *cmd,char *ack,uint16_t waittime);
static char ESP8266_consta_check(void);
static void ESP8266_get_wanip(char* ipbuf);
static void WIFI_sendData(char* fmt,...);

// WIFI信息  联网的WIFI名称和密码
const char* WIFI_id="MNIAS";
const char* WIFI_password="0123456789";

/**
	* @brief  向WIFI串口发送数据
	* @param  fmt: 类似printf的数据格式
  * @retval None
  * @note   None
*/
void WIFI_sendData(char* fmt,...)  
{  
	uint16_t i,j; 
	va_list ap; 
	va_start(ap,fmt);
	vsprintf((char*)WIFI_USART_TX_BUF,fmt,ap);
	va_end(ap);
	i = strlen((const char*)WIFI_USART_TX_BUF);		
	for(j=0; j<i; j++)						
	{
	  while(USART_GetFlagStatus(WIFI_USARTx,USART_FLAG_TC)==RESET); 
		USART_SendData(WIFI_USARTx,WIFI_USART_TX_BUF[j]); 
	} 
}
/**
	* @brief  清零缓存区并清零接收标志
	* @param  None
  * @retval None
  * @note   None
*/
void ESP8266_clear(void)
{
	memset(WIFI_USART_RX_BUF, 0, WIFI_USART_MAX_RECV_LEN);
	WIFI_USART_RX_STA = 0;
}
/**
	* @brief  检测应答
	* @param  str: 期待的应答结果
  * @retval 0: 没有接收到期待应答
	* @retval !0: 其他值代表期待应答结果的位置
	* @note   None
*/
static char* ESP8266_check_cmd(char *str)
{
	char *strx=0;
	// 接收到一次数据了
	if(WIFI_USART_RX_STA&0X8000)		
	{ 
		// 添加结束符
		WIFI_USART_RX_BUF[WIFI_USART_RX_STA&0X7FFF]=0;
		// 检索字符串
		strx=strstr(WIFI_USART_RX_BUF,str);
	} 
	return strx;
}
/**
	* @brief  向WIFI发送命令
	* @param  cmd: 发送的命令字符串
	* @param	ack: 期待的应答结果,如果为空,则表示不需要等待应答
	* @param	waittime: 等待时间(单位:10ms)
	* @retval 0: 发送成功(得到了期待的应答结果), 
	* @retval	1: 发送失败
	* @note   None
*/
static char ESP8266_send_cmd(char *cmd,char *ack,uint16_t waittime)
{
	char res=0; 
	WIFI_USART_RX_STA=0;
	//发送命令
	WIFI_sendData("%s",cmd);	
	if(ack&&waittime)		//需要等待应答
	{
		while(--waittime)	//等待倒计时
		{
			DelayClass.DelayMs(10);
			if(WIFI_USART_RX_STA&0X8000)//接收到期待的应答结果
			{
				if(*ESP8266_check_cmd(ack))
				{
					break; // 得到有效数据 
				}
					WIFI_USART_RX_STA=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
} 
/**
	* @brief  退出透传
	* @param  None
	* @retval 0: 退出成功
	* @retval 1: 退出失败
  * @note   无后缀发送"+++"退出透传
*/
void ESP8266_quit_trans(void)   
{
	while(ESP8266_send_cmd("AT+CIPMODE=0\r\n","OK",100))
	{
		while((WIFI_USARTx->SR&0X40)==0);	// 等待发送空
		WIFI_USARTx->DR='+';      
		DelayClass.DelayMs(12);	// 大于串口组帧时间(10ms)
		while((WIFI_USARTx->SR&0X40)==0);
		WIFI_USARTx->DR='+';      
		DelayClass.DelayMs(12);
		while((WIFI_USARTx->SR&0X40)==0);
		WIFI_USARTx->DR='+';  	
		DelayClass.DelayMs(100);	// 等待100ms
		ESP8266_send_cmd("AT+CIPCLOSE\r\n","OK",50);
	}
}
/**
	* @brief  获取WIFI连接状态
	* @param  None
	* @retval 0: 未连接
	* @retval 1: 连接成功
  * @note   None
*/
static char ESP8266_consta_check(void)
{
	char *p;
	char res;
	ESP8266_quit_trans(); // 退出透传 
	//发送AT+CIPSTATUS指令,查询连接状态
	ESP8266_send_cmd("AT+CIPSTATUS",":",50);	
	p=ESP8266_check_cmd("+CIPSTATUS:"); 
	res=*p;
	return res;
}
/**
	* @brief  获取Client ip地址
	* @param  ipbuf: ip地址输出缓存区
  * @retval None
  * @note   None
*/
static void ESP8266_get_wanip(char* ipbuf)
{
	char *p,*p1;
	//获取WAN IP地址失败
	if(ESP8266_send_cmd("AT+CIFSR","OK",50))
	{
		ipbuf[0]=0;
		return;
	}		
	p=ESP8266_check_cmd("\"");
	p1=(char*)strstr((const char*)(p+1),"\"");
	*p1=0;
	sprintf((char*)ipbuf,"%s",p+1);	
}
/**
	* @brief  删除指定字符并重组
	* @param  str[]: 要修改的字符串
	* @param  target: 要删除的字符
  * @retval None
  * @note   None
*/
void Delete_char(char str[],char target)
{
	int i,j;
	for(i=0, j=0; i < strlen(str); i++)
	{
		if(str[i] != target)
		{
			str[j++] = str[i];
		}
		// printf("J:%c I:%c\n", str[j-1], str[i]);
	}
	str[j] = '\0';
}
/**
	* @brief  WIFI复位引脚配置
	* @param  None
  * @retval None
  * @note   None
*/
void WIFI_RESET_GPIO_Congfig(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
	DelayClass.DelayMs(100);
	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	DelayClass.DelayMs(500);
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
	DelayClass.DelayMs(1000);
}
/**
	* @brief  连接WIFI
	* @param  None
  * @retval None
  * @note   None
*/
void Connect_wifi(void)
{
	char p[40];

	#ifdef DEBUG_printf
	printf("1. AT\n");
	#endif
	while(ESP8266_send_cmd("AT+CWMODE=1\r\n","OK",100));		//设置WIFI STA模式
	#ifdef DEBUG_printf
	printf("2. AT+CWMODE=1\n");
	#endif
	while(ESP8266_send_cmd("AT+CIPMUX=0\r\n","OK",100));   //0：单连接，1：多连接
	#ifdef DEBUG_printf
	printf("3. AT+CIPMUX=0\n");
	#endif
	sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"\r\n",WIFI_id,WIFI_password);//设置无线参数:ssid,密码
	while(ESP8266_send_cmd(p,"GOT IP",200));  //连接目标路由器,并且获得IP
	#ifdef DEBUG_printf
	printf("4. WIFI CONNECT\n");
	#endif
}
/**
	* @brief  获取实时天气
	* @param  None
  * @retval None
  * @note   心知天气API格式
*/
void Connect_wea_port(void)
{
	char p[40];
	char res;
	ESP8266_send_cmd("AT+CIPCLOSE\r\n","OK",50);
	sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"116.62.81.138\",80\r\n");
	res = ESP8266_send_cmd(p,"CONNECT",200);
	if(res) 
	{
		#ifdef DEBUG_printf
		printf("conncet weather failed\n");
		#endif
	} 
	else 
	{
		#ifdef DEBUG_printf
		printf("connect weather successed\n");
		#endif
	}
	ESP8266_send_cmd("AT+CIPMODE=1\r\n","OK",100);
	res = ESP8266_send_cmd("AT+CIPSEND\r\n","OK",100);
	if(res)
	{	
		#ifdef DEBUG_printf
		printf("weather data error\n");
		#endif
	}
	else
	{
		#ifdef DEBUG_printf
		printf("weather data start\n");
		#endif
	}
	ESP8266_clear();   //清空
	WIFI_sendData("GET https://api.seniverse.com/v3/weather/now.json?key=SKrmB3PfnSu2lVCR6&location=zhengzhou&language=zh-Hans&unit=c\r\n");
	DelayClass.DelayMs(500);
	if(WIFI_USART_RX_STA&0X8000)		//此时再次接到一次数据，为天气的数据
	{ 
		WIFI_USART_RX_BUF[WIFI_USART_RX_STA&0X7FFF]=0;//添加结束符
		#ifdef DEBUG_printf
		printf("%s\n",WIFI_USART_RX_BUF);
		#endif
	}
}
/**
	* @brief  获取实时时间
	* @param  None
  * @retval None
  * @note   NowAPI格式
*/
void Connect_time_port(void)
{
	char pp[40];
	char res;
	ESP8266_send_cmd("AT+CIPCLOSE\r\n","OK",50);
	sprintf((char*)pp,"AT+CIPSTART=\"TCP\",\"103.205.5.134\",88\r\n");
	res = ESP8266_send_cmd(pp,"CONNECT\r\n",200);
	if(res) 
	{
		#ifdef DEBUG_printf
		printf("conncet time failed\n");
		#endif
	} 
	else 
	{
		#ifdef DEBUG_printf
		printf("connect time successed\n");
		#endif
	}
	ESP8266_send_cmd("AT+CIPMODE=1\r\n","OK",100);
	res = ESP8266_send_cmd("AT+CIPSEND\r\n","OK",100);
	if(res)
	{	
		#ifdef DEBUG_printf
		printf("time data error\n");
		#endif
	}
	else
	{
		#ifdef DEBUG_printf
		printf("time data start\n");
		#endif
	}
	ESP8266_clear();   //清空
	WIFI_sendData("GET http://api.k780.com:88/?app=life.time&appkey=64669&sign=f6114926ae7705fce3e2eabc4779495b&format=json\r\n");
	DelayClass.DelayMs(500);
	if(WIFI_USART_RX_STA&0X8000)		//此时再次接到一次数据，为json的数据
	{ 
		WIFI_USART_RX_BUF[WIFI_USART_RX_STA&0X7FFF]=0;//添加结束符
		#ifdef DEBUG_printf
		printf("%s\n",WIFI_USART_RX_BUF);
		#endif
	}
}

